home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / bisonpcb / lalr.c < prev    next >
C/C++ Source or Header  |  1987-02-12  |  14KB  |  737 lines

  1. /* Compute look-ahead criteria for bison,
  2.    Copyright (C) 1984, 1986 Bob Corbett and Free Software Foundation, Inc.
  3.   
  4. BISON is distributed in the hope that it will be useful, but WITHOUT ANY
  5. WARRANTY.  No author or distributor accepts responsibility to anyone
  6. for the consequences of using it or for whether it serves any
  7. particular purpose or works at all, unless he says so in writing.
  8. Refer to the BISON General Public License for full details.
  9.   
  10. Everyone is granted permission to copy, modify and redistribute BISON,
  11. but only under the conditions described in the BISON General Public
  12. License.  A copy of this license is supposed to have been given to you
  13. along with BISON so you can know your rights and responsibilities.  It
  14. should be in a file named COPYING.  Among other things, the copyright
  15. notice and this notice must be preserved on all copies.
  16.   
  17.  In other words, you are welcome to use, share and improve this program.
  18.  You are forbidden to forbid anyone else to use, share and improve
  19.  what you give them.   Help stamp out software-hoarding!  */
  20.  
  21. /* Compute how to make the finite state machine deterministic;
  22.  find which rules need lookahead in each state, and which lookahead tokens they accept.
  23.   
  24. lalr(), the entry point, builds these data structures:
  25.   
  26. goto_map, from_state and to_state 
  27.  record each shift transition which accepts a variable (a nonterminal).
  28. ngotos is the number of such transitions.
  29. from_state[t] is the state number which a transition leads from
  30. and to_state[t] is the state number it leads to.
  31. All the transitions that accept a particular variable are grouped together and
  32. goto_map[i - ntokens] is the index in from_state and to_state of the first of them.
  33.   
  34. consistent[s] is nonzero if no lookahead is needed to decide what to do in state s.
  35.   
  36. LAruleno is a vector which records the rules that need lookahead in various states.
  37. The elements of LAruleno that apply to state s are those from
  38.  lookaheads[s] through lookaheads[s+1]-1.
  39. Each element of LAruleno is a rule number.
  40.   
  41. If lr is the length of LAruleno, then a number from 0 to lr-1 
  42. can specify both a rule and a state where the rule might be applied.
  43.   
  44. LA is a lr by ntokens matrix of bits.
  45. LA[l, i] is 1 if the rule LAruleno[l] is applicable in the appropriate state
  46.  when the next token is symbol i.
  47. If LA[l, i] and LA[l, j] are both 1 for i != j, it is a conflict.
  48. */
  49.  
  50. /*
  51.  * Port to PC by Whit Gregg
  52.  *               Nourse, Gregg & Browne, Inc.
  53.  *         1 Horizon Road
  54.  *         Fort Lee, NJ  07024
  55.  */
  56.  
  57.  
  58. #include <stdio.h>
  59. #include <malloc.h>
  60. #include "machine.h"
  61. #include "types.h"
  62. #include "state.h"
  63. #include "new.h"
  64. #include "gram.h"
  65. #include "func.h"
  66.  
  67.  
  68.     extern short **derives;
  69. extern char *nullable;
  70.  
  71.  
  72. int tokensetsize;
  73. short *lookaheads;
  74. short *LAruleno;
  75. unsigned *LA;
  76. short *accessing_symbol;
  77. char *consistent;
  78. core **state_table;
  79. shifts **shift_table;
  80. reductions **reduction_table;
  81. short *goto_map;
  82. short *from_state;
  83. short *to_state;
  84.  
  85. short **transpose();
  86.  
  87.  
  88. static int infinity;
  89. static int maxrhs;
  90. static int ngotos;
  91. static unsigned *F;
  92. static short **includes;
  93. static shorts **lookback;
  94. static short **R;
  95. static short *INDEX;
  96. static short *VERTICES;
  97. static int top;
  98.  
  99.  
  100.  
  101. void 
  102. lalr()
  103. {                /* WG */
  104.     tokensetsize = WORDSIZE(ntokens);
  105.  
  106.     set_state_table();
  107.     set_accessing_symbol();
  108.     set_shift_table();
  109.     set_reduction_table();
  110.     set_maxrhs();
  111.     initialize_LA();
  112.     set_goto_map();
  113.     initialize_F();
  114.     build_relations();
  115.     compute_FOLLOWS();
  116.     compute_lookaheads();
  117.     }
  118.  
  119.  
  120.  
  121. void 
  122. set_state_table()
  123. {                /* WG */
  124.     register core *sp;
  125.  
  126.     state_table = NEW2(nstates, core *);
  127.  
  128.     for (sp = first_state; sp; sp = sp->next)
  129.         state_table[sp->number] = sp;
  130.     }
  131.  
  132.  
  133.  
  134. void 
  135. set_accessing_symbol()
  136. {                /* WG */
  137.     register core *sp;
  138.  
  139.     accessing_symbol = NEW2(nstates, short);
  140.  
  141.     for (sp = first_state; sp; sp = sp->next)
  142.         accessing_symbol[sp->number] = sp->accessing_symbol;
  143.     }
  144.  
  145.  
  146.  
  147. void 
  148. set_shift_table()
  149. {                /* WG */
  150.     register shifts *sp;
  151.  
  152.     shift_table = NEW2(nstates, shifts *);
  153.  
  154.     for (sp = first_shift; sp; sp = sp->next)
  155.         shift_table[sp->number] = sp;
  156.     }
  157.  
  158.  
  159.  
  160. void 
  161. set_reduction_table()
  162. {                /* WG */
  163.     register reductions *rp;
  164.  
  165.     reduction_table = NEW2(nstates, reductions *);
  166.  
  167.     for (rp = first_reduction; rp; rp = rp->next)
  168.         reduction_table[rp->number] = rp;
  169.     }
  170.  
  171.  
  172.  
  173. void 
  174. set_maxrhs()
  175. {                /* WG */
  176.     register short *itemp;
  177.     register int length;
  178.     register int max;
  179.  
  180.     length = 0;
  181.     max = 0;
  182.     for (itemp = ritem; *itemp; itemp++) {
  183.         if (*itemp > 0) {
  184.             length++;
  185.             }
  186.         else {
  187.             if (length > max)
  188.                 max = length;
  189.             length = 0;
  190.             }
  191.         }
  192.  
  193.     maxrhs = max;
  194.     }
  195.  
  196.  
  197.  
  198. void 
  199. initialize_LA()
  200. {                /* WG */
  201.     register int i;
  202.     register int j;
  203.     register int count;
  204.     register reductions *rp;
  205.     register shifts *sp;
  206.     register short *np;
  207.  
  208.     consistent = NEW2(nstates, char);
  209.     lookaheads = NEW2(nstates + 1, short);
  210.  
  211.     count = 0;
  212.     for (i = 0; i < nstates; i++) {
  213.         register int j;
  214.  
  215.         lookaheads[i] = count;
  216.  
  217.         rp = reduction_table[i];
  218.         sp = shift_table[i];
  219.         if (rp && (rp->nreds > 1
  220.             || (sp && !ISVAR(accessing_symbol[sp->shifts[0]]))))
  221.             count += rp->nreds;
  222.         else
  223.             consistent[i] = 1;
  224.  
  225.         if (sp)
  226.             for (j = 0; j < sp->nshifts; j++) {
  227.                 if (accessing_symbol[sp->shifts[j]] == error_token_number) {
  228.                     consistent[i] = 0;
  229.                     break;
  230.                     }
  231.                 }
  232.         }
  233.  
  234.     lookaheads[nstates] = count;
  235.  
  236.     LA = NEW2(count * tokensetsize, unsigned);
  237.     LAruleno = NEW2(count, short);
  238.     lookback = NEW2(count, shorts *);
  239.  
  240.     np = LAruleno;
  241.     for (i = 0; i < nstates; i++) {
  242.         if (!consistent[i]) {
  243.             if (rp = reduction_table[i])
  244.                 for (j = 0; j < rp->nreds; j++)
  245.                     *np++ = rp->rules[j];
  246.             }
  247.         }
  248.     }
  249.  
  250.  
  251.  
  252. void 
  253. set_goto_map()
  254. {                /* WG */
  255.     register shifts *sp;
  256.     register int i;
  257.     register int symbol;
  258.     register int k;
  259.     register short *temp_map;
  260.     register int state2;
  261.     register int state1;
  262.  
  263.     goto_map = NEW2(nvars + 1, short) -ntokens;
  264.     temp_map = NEW2(nvars + 1, short) -ntokens;
  265.  
  266.     ngotos = 0;
  267.     for (sp = first_shift; sp; sp = sp->next) {
  268.         for (i = sp->nshifts - 1; i >= 0; i--) {
  269.             symbol = accessing_symbol[sp->shifts[i]];
  270.  
  271.             if (ISTOKEN(symbol))
  272.                 break;
  273.  
  274.             if (ngotos == MAXSHORT)
  275.                 toomany("gotos");
  276.  
  277.             ngotos++;
  278.             goto_map[symbol]++;
  279.             }
  280.         }
  281.  
  282.     k = 0;
  283.     for (i = ntokens; i < nsyms; i++) {
  284.         temp_map[i] = k;
  285.         k += goto_map[i];
  286.         }
  287.  
  288.     for (i = ntokens; i < nsyms; i++)
  289.         goto_map[i] = temp_map[i];
  290.  
  291.     goto_map[nsyms] = ngotos;
  292.     temp_map[nsyms] = ngotos;
  293.  
  294.     from_state = NEW2(ngotos, short);
  295.     to_state = NEW2(ngotos, short);
  296.  
  297.     for (sp = first_shift; sp; sp = sp->next) {
  298.         state1 = sp->number;
  299.         for (i = sp->nshifts - 1; i >= 0; i--) {
  300.             state2 = sp->shifts[i];
  301.             symbol = accessing_symbol[state2];
  302.  
  303.             if (ISTOKEN(symbol))
  304.                 break;
  305.  
  306.             k = temp_map[symbol]++;
  307.             from_state[k] = state1;
  308.             to_state[k] = state2;
  309.             }
  310.         }
  311.  
  312.     FREE(temp_map + ntokens);
  313.     }
  314.  
  315.  
  316.  
  317. /*  Map_goto maps a state/symbol pair into its numeric representation.    */
  318.  
  319. int
  320. map_goto(state, symbol)
  321.     int state;
  322.     int symbol;
  323. {
  324.     register int high;
  325.     register int low;
  326.     register int middle;
  327.     register int s;
  328.  
  329.     low = goto_map[symbol];
  330.     high = goto_map[symbol + 1];
  331.  
  332.     while (low <= high) {
  333.         middle = (low + high) / 2;
  334.         s = from_state[middle];
  335.         if (s == state)
  336.             return (middle);
  337.         else if (s < state)
  338.             low = middle + 1;
  339.         else
  340.             high = middle - 1;
  341.         }
  342.  
  343.     berror("map_goto");
  344.  
  345. /* NOTREACHED */
  346.     }
  347.  
  348.  
  349.  
  350. void 
  351. initialize_F()
  352. {                /* WG */
  353.     register int i;
  354.     register int j;
  355.     register int k;
  356.     register shifts *sp;
  357.     register short *edge;
  358.     register unsigned *rowp;
  359.     register short *rp;
  360.     register short **reads;
  361.     register int nedges;
  362.     register int stateno;
  363.     register int symbol;
  364.     register int nwords;
  365.  
  366.     nwords = ngotos * tokensetsize;
  367.     F = NEW2(nwords, unsigned);
  368.  
  369.     reads = NEW2(ngotos, short *);
  370.     edge = NEW2(ngotos + 1, short);
  371.     nedges = 0;
  372.  
  373.     rowp = F;
  374.     for (i = 0; i < ngotos; i++) {
  375.         stateno = to_state[i];
  376.         sp = shift_table[stateno];
  377.  
  378.         if (sp) {
  379.             k = sp->nshifts;
  380.  
  381.             for (j = 0; j < k; j++) {
  382.                 symbol = accessing_symbol[sp->shifts[j]];
  383.                 if (ISVAR(symbol))
  384.                     break;
  385.                 SETBIT(rowp, symbol);
  386.                 }
  387.  
  388.             for (; j < k; j++) {
  389.                 symbol = accessing_symbol[sp->shifts[j]];
  390.                 if (nullable[symbol])
  391.                     edge[nedges++] = map_goto(stateno, symbol);
  392.                 }
  393.  
  394.             if (nedges) {
  395.                 reads[i] = rp = NEW2(nedges + 1, short);
  396.  
  397.                 for (j = 0; j < nedges; j++)
  398.                     rp[j] = edge[j];
  399.  
  400.                 rp[nedges] = -1;
  401.                 nedges = 0;
  402.                 }
  403.             }
  404.  
  405.         rowp += tokensetsize;
  406.         }
  407.  
  408.     digraph(reads);
  409.  
  410.     for (i = 0; i < ngotos; i++) {
  411.         if (reads[i])
  412.             FREE(reads[i]);
  413.         }
  414.  
  415.     FREE(reads);
  416.     FREE(edge);
  417.     }
  418.  
  419.  
  420.  
  421. void 
  422. build_relations()
  423. {                /* WG */
  424.     register int i;
  425.     register int j;
  426.     register int k;
  427.     register short *rulep;
  428.     register short *rp;
  429.     register shifts *sp;
  430.     register int length;
  431.     register int nedges;
  432.     register int done;
  433.     register int state1;
  434.     register int stateno;
  435.     register int symbol1;
  436.     register int symbol2;
  437.     register short *shortp;
  438.     register short *edge;
  439.     register short *states;
  440.     register short **new_includes;
  441.  
  442.     includes = NEW2(ngotos, short *);
  443.     edge = NEW2(ngotos + 1, short);
  444.     states = NEW2(maxrhs + 1, short);
  445.  
  446.     for (i = 0; i < ngotos; i++) {
  447.         nedges = 0;
  448.         state1 = from_state[i];
  449.         symbol1 = accessing_symbol[to_state[i]];
  450.  
  451.         for (rulep = derives[symbol1]; *rulep > 0; rulep++) {
  452.             length = 1;
  453.             states[0] = state1;
  454.             stateno = state1;
  455.  
  456.             for (rp = ritem + rrhs[*rulep]; *rp > 0; rp++) {
  457.                 symbol2 = *rp;
  458.                 sp = shift_table[stateno];
  459.                 k = sp->nshifts;
  460.  
  461.                 for (j = 0; j < k; j++) {
  462.                     stateno = sp->shifts[j];
  463.                     if (accessing_symbol[stateno] == symbol2)
  464.                         break;
  465.                     }
  466.  
  467.                 states[length++] = stateno;
  468.                 }
  469.  
  470.             if (!consistent[stateno])
  471.                 add_lookback_edge(stateno, *rulep, i);
  472.  
  473.             length--;
  474.             done = 0;
  475.             while (!done) {
  476.                 done = 1;
  477.                 rp--;
  478.                 /*
  479.                  * JF added rp>=ritem &&   I hope to god its
  480.                  * right! 
  481.                  */
  482.                 if (rp >= ritem && ISVAR(*rp)) {
  483.                     stateno = states[--length];
  484.                     edge[nedges++] = map_goto(stateno, *rp);
  485.                     if (nullable[*rp])
  486.                         done = 0;
  487.                     }
  488.                 }
  489.             }
  490.  
  491.         if (nedges) {
  492.             includes[i] = shortp = NEW2(nedges + 1, short);
  493.             for (j = 0; j < nedges; j++)
  494.                 shortp[j] = edge[j];
  495.             shortp[nedges] = -1;
  496.             }
  497.         }
  498.  
  499.     new_includes = transpose(includes, ngotos);
  500.  
  501.     for (i = 0; i < ngotos; i++)
  502.         if (includes[i])
  503.             FREE(includes[i]);
  504.  
  505.     FREE(includes);
  506.  
  507.     includes = new_includes;
  508.  
  509.     FREE(edge);
  510.     FREE(states);
  511.     }
  512.  
  513.  
  514.  
  515. void 
  516. add_lookback_edge(stateno, ruleno, gotono)    /* WG */
  517.     int stateno;
  518.     int ruleno;
  519.     int gotono;
  520. {
  521.     register int i;
  522.     register int k;
  523.     register int found;
  524.     register shorts *sp;
  525.  
  526.     i = lookaheads[stateno];
  527.     k = lookaheads[stateno + 1];
  528.     found = 0;
  529.     while (!found && i < k) {
  530.         if (LAruleno[i] == ruleno)
  531.             found = 1;
  532.         else
  533.             i++;
  534.         }
  535.  
  536.     if (found == 0)
  537.         berror("add_lookback_edge");
  538.  
  539.     sp = NEW(shorts);
  540.     sp->next = lookback[i];
  541.     sp->value = gotono;
  542.     lookback[i] = sp;
  543.     }
  544.  
  545.  
  546.  
  547. short **
  548. transpose(R, n)
  549.     short **R;
  550.     int n;
  551. {
  552.     register short **new_R;
  553.     register short **temp_R;
  554.     register short *nedges;
  555.     register short *sp;
  556.     register int i;
  557.     register int k;
  558.  
  559.     nedges = NEW2(n, short);
  560.  
  561.     for (i = 0; i < n; i++) {
  562.         sp = R[i];
  563.         if (sp) {
  564.             while (*sp >= 0)
  565.                 nedges[*sp++]++;
  566.             }
  567.         }
  568.  
  569.     new_R = NEW2(n, short *);
  570.     temp_R = NEW2(n, short *);
  571.  
  572.     for (i = 0; i < n; i++) {
  573.         k = nedges[i];
  574.         if (k > 0) {
  575.             sp = NEW2(k + 1, short);
  576.             new_R[i] = sp;
  577.             temp_R[i] = sp;
  578.             sp[k] = -1;
  579.             }
  580.         }
  581.  
  582.     FREE(nedges);
  583.  
  584.     for (i = 0; i < n; i++) {
  585.         sp = R[i];
  586.         if (sp) {
  587.             while (*sp >= 0)
  588.                 *temp_R[*sp++]++ = i;
  589.             }
  590.         }
  591.  
  592.     FREE(temp_R);
  593.  
  594.     return (new_R);
  595.     }
  596.  
  597.  
  598.  
  599. void 
  600. compute_FOLLOWS()
  601. {                /* WG */
  602.     register int i;
  603.  
  604.     digraph(includes);
  605.  
  606.     for (i = 0; i < ngotos; i++) {
  607.         if (includes[i])
  608.             FREE(includes[i]);
  609.         }
  610.  
  611.     FREE(includes);
  612.     }
  613.  
  614.  
  615.  
  616. void 
  617. compute_lookaheads()
  618. {                /* WG */
  619.     register int i;
  620.     register int n;
  621.     register unsigned *fp1;
  622.     register unsigned *fp2;
  623.     register unsigned *fp3;
  624.     register shorts *sp;
  625.     register unsigned *rowp;
  626.  
  627. /*   register short *rulep; JF unused */
  628. /*  register int count; JF unused */
  629.     register shorts *sptmp;    /* JF */
  630.  
  631.     rowp = LA;
  632.     n = lookaheads[nstates];
  633.     for (i = 0; i < n; i++) {
  634.         fp3 = rowp + tokensetsize;
  635.         for (sp = lookback[i]; sp; sp = sp->next) {
  636.             fp1 = rowp;
  637.             fp2 = F + tokensetsize * sp->value;
  638.             while (fp1 < fp3)
  639.                 *fp1++ |= *fp2++;
  640.             }
  641.  
  642.         rowp = fp3;
  643.         }
  644.  
  645.     for (i = 0; i < n; i++) {    /* JF removed ref to freed storage */
  646.         for (sp = lookback[i]; sp; sp = sptmp) {
  647.             sptmp = sp->next;
  648.             FREE(sp);
  649.             }
  650.         }
  651.  
  652.     FREE(lookback);
  653.     FREE(F);
  654.     }
  655.  
  656.  
  657.  
  658. void 
  659. digraph(relation)        /* WG */
  660.     short **relation;
  661. {
  662.     register int i;
  663.  
  664.     infinity = ngotos + 2;
  665.     INDEX = NEW2(ngotos + 1, short);
  666.     VERTICES = NEW2(ngotos + 1, short);
  667.     top = 0;
  668.  
  669.     R = relation;
  670.  
  671.     for (i = 0; i < ngotos; i++)
  672.         INDEX[i] = 0;
  673.  
  674.     for (i = 0; i < ngotos; i++) {
  675.         if (INDEX[i] == 0 && R[i])
  676.             traverse(i);
  677.         }
  678.  
  679.     FREE(INDEX);
  680.     FREE(VERTICES);
  681.     }
  682.  
  683.  
  684.  
  685. void 
  686. traverse(i)            /* WG */
  687.     register int i;
  688. {
  689.     register unsigned *fp1;
  690.     register unsigned *fp2;
  691.     register unsigned *fp3;
  692.     register int j;
  693.     register short *rp;
  694.  
  695.     int height;
  696.     unsigned *base;
  697.  
  698.     VERTICES[++top] = i;
  699.     INDEX[i] = height = top;
  700.  
  701.     base = F + i * tokensetsize;
  702.     fp3 = base + tokensetsize;
  703.  
  704.     rp = R[i];
  705.     if (rp) {
  706.         while ((j = *rp++) >= 0) {
  707.             if (INDEX[j] == 0)
  708.                 traverse(j);
  709.  
  710.             if (INDEX[i] > INDEX[j])
  711.                 INDEX[i] = INDEX[j];
  712.  
  713.             fp1 = base;
  714.             fp2 = F + j * tokensetsize;
  715.  
  716.             while (fp1 < fp3)
  717.                 *fp1++ |= *fp2++;
  718.             }
  719.         }
  720.  
  721.     if (INDEX[i] == height) {
  722.         for (;;) {
  723.             j = VERTICES[top--];
  724.             INDEX[j] = infinity;
  725.  
  726.             if (i == j)
  727.                 break;
  728.  
  729.             fp1 = base;
  730.             fp2 = F + j * tokensetsize;
  731.  
  732.             while (fp1 < fp3)
  733.                 *fp2++ = *fp1++;
  734.             }
  735.         }
  736.     }
  737.